﻿using CleanArchitecture.Infrastructure.Entities.Business;
using CleanArchitecture.Infrastructure.Entities.Common;
using CleanArchitecture.Infrastructure.Interfaces;
using CleanArchitecture.Infrastructure.Interfaces.Business;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CleanArchitecture.Infrastructure.Services.Business
{
    public partial class ActiveLogService : IActiveLogService
    {
        #region Fields
        private readonly IDbContext _dbContext;
        private readonly IRepository<ActiveLog> _activelogService;
        #endregion

        #region Ctor
        public ActiveLogService(IDbContext dbContext,
            IRepository<ActiveLog> activelogService)
        {
            this._activelogService = activelogService;
            this._dbContext = dbContext;
        }
        #endregion

        public void InsertLog(ActiveLog entity)
        {
            if (entity == null)
                throw new ArgumentNullException(nameof(entity));

            _activelogService.Insert(entity);
        }

        public IDictionary<string, int> StatisticsNewsVistCountWithin7Days()
        {
            string selectSQL = "SELECT DATE_FORMAT(visitdate,'%m-%d') as Date,IFNULL(COUNT(pv.CreatedOnTimeUtc), 0) as VisitCount FROM (";
            selectSQL += "SELECT curdate() as visitdate";
            selectSQL += " union all SELECT date_sub(curdate(), interval 1 day) as visitdate";
            selectSQL += " union all SELECT date_sub(curdate(), interval 2 day) as visitdate";
            selectSQL += " union all SELECT date_sub(curdate(), interval 3 day) as visitdate";
            selectSQL += " union all SELECT date_sub(curdate(), interval 4 day) as visitdate";
            selectSQL += " union all SELECT date_sub(curdate(), interval 5 day) as visitdate";
            selectSQL += " union all SELECT date_sub(curdate(), interval 6 day) as visitdate";
            selectSQL += ") as total";
            selectSQL += " LEFT JOIN bus_activelog pv ON DATE_FORMAT(pv.CreatedOnTimeUtc,'%Y-%m-%d') = total.visitdate";
            selectSQL += $" AND pv.ActiveName = '{ActiveLogName.VisitNewsPage}'";
            selectSQL += " GROUP BY visitdate ORDER BY visitdate";

            var result = _dbContext.QueryFromSql<NewsVisitQuery>(selectSQL).ToDictionary(x => x.Date, x => x.VisitCount);
            return result;
        }
        /// <summary>
        /// 统计文章访问量总数
        /// </summary>
        /// <returns></returns>
        public int StatisticsNewsVistCount()
        {
            var newsVisitCountQuery = _activelogService.TableNoTracking.Where(v => v.ActiveName == nameof(ActiveLogName.VisitNewsPage) && v.EntityName == nameof(NewsItem))
                                         .Count();
            return newsVisitCountQuery;
        }

        public IDictionary<string, int> StatisticsBlogVistCountWithin7Days()
        {
            string selectSQL = "SELECT DATE_FORMAT(visitdate,'%m-%d') as Date,IFNULL(COUNT(pv.CreatedOnTimeUtc), 0) as VisitCount FROM (";
            selectSQL += "SELECT curdate() as visitdate";
            selectSQL += " union all SELECT date_sub(curdate(), interval 1 day) as visitdate";
            selectSQL += " union all SELECT date_sub(curdate(), interval 2 day) as visitdate";
            selectSQL += " union all SELECT date_sub(curdate(), interval 3 day) as visitdate";
            selectSQL += " union all SELECT date_sub(curdate(), interval 4 day) as visitdate";
            selectSQL += " union all SELECT date_sub(curdate(), interval 5 day) as visitdate";
            selectSQL += " union all SELECT date_sub(curdate(), interval 6 day) as visitdate";
            selectSQL += ") as total";
            selectSQL += " LEFT JOIN bus_activelog pv ON DATE_FORMAT(pv.CreatedOnTimeUtc,'%Y-%m-%d') = total.visitdate";
            selectSQL += $" AND pv.ActiveName = '{ActiveLogName.VisitBlogPage}'";
            selectSQL += " GROUP BY visitdate ORDER BY visitdate";

            var result = _dbContext.QueryFromSql<NewsVisitQuery>(selectSQL).ToDictionary(x => x.Date, x => x.VisitCount);
            return result;
        }
        /// <summary>
        /// 通过分页查询获取到的文章ID统计查询每篇文章的访问量,及每篇文章的点赞数量
        /// </summary>
        /// <param name="newsids"></param>
        /// <returns></returns>
        public IList<PageVisitQuery> StatisticsNewsCountsByNewsIds(int[] newsids)
        {
            if (newsids == null) return null;
            if (newsids.Length <= 0) return null;
            string selectSQL = string.Empty; //多次一举只为排版好看
            selectSQL += "SELECT logtbl.EntityId AS Id,";
            selectSQL += $"SUM(CASE WHEN logtbl.ActiveName = '{ActiveLogName.VisitNewsPage}' THEN 1 ELSE 0 END) AS VisitCount,";
            selectSQL += $"SUM(CASE WHEN logtbl.ActiveName = '{ActiveLogName.NewsPageLike}' THEN 1 ELSE 0 END) AS LikeCount";
            selectSQL += " FROM(";
            selectSQL += $" SELECT '{ActiveLogName.VisitNewsPage}' AS ColName";
            selectSQL += "  UNION ALL";
            selectSQL += $" SELECT '{ActiveLogName.NewsPageLike}' AS ColName";
            selectSQL += ") AS temp1 LEFT JOIN bus_activelog AS logtbl ON temp1.ColName = logtbl.ActiveName";
            selectSQL += " WHERE logtbl.EntityId IN(" + string.Join(",", newsids) + ")";
            selectSQL += " GROUP BY logtbl.EntityId";
            var result = _dbContext.QueryFromSql<PageVisitQuery>(selectSQL).ToList();
            return result;
        }
        /// <summary>
        /// 通过分页查询获取到的博客ID统计查询每篇博客的访问量,及每篇博客的点击数量
        /// </summary>
        /// <param name="blogids"></param>
        /// <returns></returns>
        public IList<PageVisitQuery> StatisticsBlogCountsByBlogIds(int[] blogids)
        {
            if (blogids == null) return null;
            if (blogids.Length <= 0) return null;
            string selectSQL = string.Empty; //多次一举只为排版好看
            selectSQL += "SELECT logtbl.EntityId AS Id,";
            selectSQL += $"SUM(CASE WHEN logtbl.ActiveName = '{ActiveLogName.VisitBlogPage}' THEN 1 ELSE 0 END) AS VisitCount,";
            selectSQL += $"SUM(CASE WHEN logtbl.ActiveName = '{ActiveLogName.BlogPageLike}' THEN 1 ELSE 0 END) AS LikeCount";
            selectSQL += " FROM(";
            selectSQL += $" SELECT '{ActiveLogName.VisitBlogPage}' AS ColName";
            selectSQL += "  UNION ALL";
            selectSQL += $" SELECT '{ActiveLogName.BlogPageLike}' AS ColName";
            selectSQL += ") AS temp1 LEFT JOIN bus_activelog AS logtbl ON temp1.ColName = logtbl.ActiveName";
            selectSQL += " WHERE logtbl.EntityId IN(" + string.Join(",", blogids) + ")";
            selectSQL += " GROUP BY logtbl.EntityId";
            var result = _dbContext.QueryFromSql<PageVisitQuery>(selectSQL).ToList();
            return result;
        }
    }
}
